import { useState, useEffect, useRef } from 'react'
import { debounce } from 'lodash-es'
import { getListByPage } from '../mock/index'
import './style/lazyList.css'
import { IList } from '../mock/index'

// 距离阈值，可以看着定义，主要用于判断滚动到底部的条件
const threshold = 1
const pageSize = 20

function LazyList() {
	// list container ref 引用
	const listRef = useRef<HTMLDivElement | null>(null)
	// 分页获取数据的页码引用
	const pageNumRef = useRef<number>(1)
	// 列表数据
	const [list, setList] = useState<IList[]>([])

	useEffect(() => {
		// 初始化 list
		const list = getListByPage(pageNumRef.current, pageSize)
		setList(list)

		// 监听滚动事件
		listRef.current?.addEventListener('scroll', handleScroll)

		// 组件销毁，取消事件监听
		return () => {
			listRef.current?.removeEventListener('scroll', handleScroll)
		}
	}, [])

	// 滑动到底部，重新设置页码，获取新的一页数据，合并到 list 里面
	const onReachBottom = () => {
		pageNumRef.current++
		const curList = getListByPage(pageNumRef.current, pageSize)
		setList((list) => list.concat(curList))
	}

	// 滚动事件，加防抖事件
	const handleScroll = debounce((e: Event) => {
		const target = e.target
		const { scrollTop, scrollHeight, offsetHeight } =
			target as EventTarget & {
				scrollTop: number
				scrollHeight: number
				offsetHeight: number
			}

		// 滚动到底部
		if (scrollHeight - scrollTop < offsetHeight + threshold) {
			onReachBottom()
		}
	}, 300)

	return (
		<div className="lazy-list-container" ref={listRef}>
			{list.length
				? list.map((item) => {
						return (
							<div key={item.id} className="item">
								懒加载 - {item.value}
							</div>
						)
				  })
				: null}
		</div>
	)
}

export default LazyList
